﻿using System;
using Sponsorship.Domain;
using Sponsorship.Domain.Persons;
using Sponsorship.Infrastructure;
using Sponsorship.ReadModel;
using Sponsorship.ReadModel.Persons;
using Sponsorship.Ui.Wpf.Commanding;
using Sponsorship.Ui.Wpf.Locator;
using Sponsorship.Ui.Wpf.Messaging;
using ICommand = System.Windows.Input.ICommand;

namespace Sponsorship.Ui.Wpf.ViewModel
{
    [Locator("PersonViewModel")]
    public class PersonViewModel : ViewModelBase
    {
        private readonly IBus _bus;
        private RelayCommand _cancelCommand;
        private DetailsOfPersonDto _detailModel;
        private readonly IReadRepository _readRepository;
        private RelayCommand _saveCommand;


        public PersonViewModel (IBus bus, IReadRepository readRepository)
        {
            _bus = bus;
            _readRepository = readRepository;
               
        }

        public string FirstName
        {
            get { return _detailModel.FirstName; }
            set
            {
                if (_detailModel.FirstName == value) return;
                _detailModel.FirstName = value;
                RaisePropertyChanged("FirstName");
            }
        }

        public string LastName
        {
            get { return _detailModel.LastName; }
            set
            {
                if (_detailModel.LastName == value) return;
                _detailModel.LastName = value;
                RaisePropertyChanged("LastName");
            }
        }

        public string Comment
        {
            get { return _detailModel.Comment; }
            set
            {
                if (_detailModel.Comment == value) return;
                _detailModel.Comment = value;
                RaisePropertyChanged("Comment");
            }
        }

        public string TelephoneNumber
        {
            get { return _detailModel.TelephoneNumber; }
            set
            {
                if (_detailModel.TelephoneNumber == value) return;
                _detailModel.TelephoneNumber = value;
                RaisePropertyChanged("TelephoneNumber");
            }
        }

        public DateTime? DateOfBirth
        {
            get { return _detailModel.DateOfBirth; }
            set
            {
                if (_detailModel.DateOfBirth == value) return;
                _detailModel.DateOfBirth = value;
                RaisePropertyChanged("DateOfBirth");
            }
        }

        public bool IsSponsorable
        {
            get { return _detailModel.IsSponsorable; }
            set
            {
                if (_detailModel.IsSponsorable == value) return;
                _detailModel.IsSponsorable = value;
                RaisePropertyChanged("IsSponsorable");
            }
        }

        public override void SetModel(Guid id)
        {
            if (id != Guid.Empty)
            {
                _detailModel = _readRepository.GetById<DetailsOfPersonDto>(Dto.GetDtoIdOf<DetailsOfPersonDto>(id));
                //_detailModel.Address = _detailModel.Address ?? new AddressDto();
            }
            else
            {
                _detailModel = new DetailsOfPersonDto();
            }

            base.SetModel(id);

            RaisePropertyChanged("FirstName");
            RaisePropertyChanged("LastName");
            RaisePropertyChanged("Comment");
            RaisePropertyChanged("TelephoneNumber");
            RaisePropertyChanged("DateOfBirth");
            RaisePropertyChanged("IsSponsorable");

        }


        private bool CanSave
        {
            get
            {
                return
                    !String.IsNullOrEmpty(FirstName) &&
                    !String.IsNullOrEmpty(LastName);
            }
        }

        private void Cancel()
        {
            Messenger.Instance.Send(this, "mainmenu");
        }

        private void Save()
        {
            bool newPerson = _detailModel.AggregateRootId.ToString() == Guid.Empty.ToString();

            if (newPerson)
            {
                var command = new EnterPerson(Guid.NewGuid(), _detailModel.FirstName, _detailModel.LastName, _detailModel.DateOfBirth, _detailModel.TelephoneNumber, SponsoringStatus.Sponsorable, _detailModel.Comment);
                _bus.Send(command);
            }
            else
            {
                var command = new ChangePerson(_detailModel.AggregateRootId, _detailModel.Version++, _detailModel.FirstName, _detailModel.LastName, _detailModel.DateOfBirth, _detailModel.TelephoneNumber, SponsoringStatus.Sponsorable, _detailModel.Comment);
                _bus.Send(command);
            }


            Cancel();
        }

        public ICommand SaveCommand
        {
            get
            {
                return _saveCommand ?? (_saveCommand = new RelayCommand(
                                                           param => Save(),
                                                           param => CanSave
                                                           ));
            }
        }

        public ICommand CancelCommand
        {
            get
            {
                return _cancelCommand ?? (_cancelCommand = new RelayCommand(
                                                               param => Cancel(),
                                                               param => true
                                                               ));
            }
        }
    }
}
